<template>
  <div>
    <el-card shadow="always" :body-style="{ padding: '20px' }">
      <CategorySelector :disabled="!isShowList"></CategorySelector>
    </el-card>

    <el-card shadow="always" :body-style="{ padding: '20px' }" style="margin-top: 20px;">
      <!-- 这个div就是我们的平台属性列表相关的东西 -->
      <div v-show="isShowList">
        <el-button type="primary" size="default" :icon="Plus" @click="showAddDiv">添加属性</el-button>
        <el-table :data="attrList" border stripe>
          <el-table-column label="序号" type="index" align="center" width="80"></el-table-column>
          <el-table-column label="属性名称" prop="attrName" width="150"></el-table-column>
          <el-table-column label="属性值名称列表">
            <template v-slot="{row}">
              <el-tag type="danger" size="default" v-for="(attrValue) in row.attrValueList" :key="attrValue.id">
                {{ attrValue.valueName }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="150">
            <template v-slot="{row}">
              <el-button type="warning" size="small" icon="ele-Edit" title="修改" @click="showUpdateDiv(row)"></el-button>
              <el-popconfirm :title="`你确定要删除${row.valueName}吗?`" @confirm="deleteAttr(row)">
                  <template #reference>
                    <el-button type="danger" size="small" title="删除属性值" icon="ele-Delete" ></el-button>
                  </template>
               </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <!-- 这个div对应的就是平台属性添加和修改的界面 -->
      <div v-show="!isShowList">
        <el-form :inline="true">
          <el-form-item label="属性名">
            <el-input placeholder="输入属性名" v-model="attrForm.attrName"></el-input>
          </el-form-item>
        </el-form>
        <el-button type="primary" size="default" @click="addAttrValue" :disabled="!attrForm.attrName">添加属性值</el-button>
        <el-button @click="isShowList = true">取消</el-button>
        <!-- 
          1、表格当中是为了展示属性值
          此时属性值列表里面什么都没有，所以表格什么都没有
          2、点击添加属性值按钮，往属性值列表中push一个属性值对象，那么表格当中自然就出现一行
          但是push的属性值对象只能确定attrId，不能确定valueName，写了就写死了，后面只要点击按钮添加的属性值
          属性值名称都一样，因此valuename必须是空串
          虽然是空串，但是我们的目的已经达到了，就是为了让表格当中出现一行去占位
          3、出现的每行使用作用域插槽，写一个输入框，这个输入框的作用就是为了让用户去决定属性值名称是什么
          4、在input当中通过v-model，把用户输入的属性值名称，绑定row.valueName身上
         -->
        <el-table :data="attrForm.attrValueList" border stripe style="margin-top:20px">
          <el-table-column label="序号" type="index" align="center" width="80"></el-table-column>
          <el-table-column label="属性值名称" prop="valueName">
            <template v-slot="{row,$index}">
              <el-input ref="inputRef" size="small" @blur="toLook(row,$index)" @keyup.enter="$event.target.blur()" v-if='row.isEdit' v-model="row.valueName" placeholder="输入属性值名称"></el-input>
              <span style="display: block; width:100%" v-else @click='toEdit(row)'>{{ row.valueName }}</span>
            </template>
          </el-table-column>
          <el-table-column label="操作">
              <template v-slot="{row,$index}">
                <el-popconfirm :title="`你确定要删除${row.valueName}吗?`" @confirm="attrForm.attrValueList.splice($index,1)">
                  <template #reference>
                    <el-button type="danger" size="small" title="删除属性值" icon="ele-Delete" ></el-button>
                  </template>
                </el-popconfirm>
              </template>
          </el-table-column>
        </el-table>
        <el-button type="primary" size="default" @click="save" :disabled="!attrForm.attrValueList.length">保存</el-button>
        <el-button @click="isShowList = true">取消</el-button>
      </div>
    </el-card>
    
  </div>
</template>
<script lang="ts">
  import { defineComponent,nextTick } from 'vue';
import attr from '@/api/attr';
import { attempt } from 'lodash';
  
  export default defineComponent({
    name:'Attr'
  })
</script>
<script lang="ts" setup>
// icon单个使用需要引入，每个组件，上面在用的时候  :icon="组件"
// 为什么可以写ele-XXX是因为已经在SvgIcon当中把所有的组件已经在插件当中全局全部注册好了
// 名字在注册的时候，要求必须是ele开头
import {Plus,Edit,Delete} from '@element-plus/icons-vue'
import {useCategoryStore} from '@/stores/category'
import { storeToRefs } from 'pinia';
import {watch,ref} from 'vue'
import attrApi,{type AttrData, type AttrValueData} from '@/api/attr'
import { ElMessage } from 'element-plus';
// 完整引入
// import _ from 'lodash'
// 按需引入
import cloneDeep from 'lodash/cloneDeep'



  // 发请求获取平台属性列表是在选中3级分类的时候才发的
  // 此时我们就考虑拿到3级id，如果3级id发生变化我们就发请求
  // 但是3级id发生变化  可能是这些情况
  // 一开始没有，后面有了
  // 一开始有，后面没了
  // 一开始有，后来值变了
  // 拿到仓库当中存储的3级分类id进行监视
  const categoryStore = useCategoryStore()
  const {category3Id,category1Id,category2Id} = storeToRefs(categoryStore)

  const attrList = ref<AttrData[]>([])
  // 这个函数专门用来发请求获取属性列表
  const getAttrList = async () => {
    try {
      const result = await attrApi.getList(
        category1Id.value as number,
        category2Id.value as number,
        category3Id.value as number
      )
      attrList.value = result
    } catch (error) {
      ElMessage.error('获取平台属性列表失败')
    }
  }

  watch(category3Id,(newVal,oldVal) => {
    if(newVal !== ''){
      getAttrList()
    }else{
      // 不需要发请求，但是需要把列表数据给清空
      attrList.value = []
    }
  },{
    immediate:true
  })




  // 平台属性的添加

  const isShowList = ref(true)

  const showAddDiv = () => {
    isShowList.value = false

    // 重置attrForm解决添加完成点取消再次添加的时候数据依然存在的bug
    attrForm.value = {
      attrName: '',
      attrValueList: [
        // {
        //   "attrId": 0,
        //   "id": 0,
        //   "valueName": "string"
        // }
      ],
      categoryId: category3Id.value, //这里一定挂载完成，数据也都初始化结束了，此时拿数据最稳妥
      categoryLevel: 3, //固定就是3级分类的id
    }
  }

// 收集数据
// {
//   "attrName": "string",
//   "attrValueList": [
//     {
      // "attrId": 0,
      // "id": 0,
      // "valueName": "string"
//     }
//   ],
//   "categoryId": 0,
//   "categoryLevel": 0,
//   "id": 0
// }
  const attrForm = ref<AttrData>({
    attrName: '',
    attrValueList: [
      // {
      //   "attrId": 0,
      //   "id": 0,
      //   "valueName": "string"
      // }
    ],
    categoryId: '',
    categoryLevel: 3, //固定就是3级分类的id
  })


  
  const inputRef = ref()

  // 点击添加属性值的按钮
  // 添加属性值的逻辑不光在添加属性的时候要用，在添加属性的时候添加属性值，属性的id是不存在的
  // 在修改属性的时候也要用这个逻辑，在修改属性的时候添加属性值，属性的id是存在的
  const addAttrValue = () => {
    attrForm.value.attrValueList.push({
      attrId: attrForm.value.id,  //添加属性的时候是undefined,修改属性的时候是有真实的id值的
      valueName: '',
      isEdit:true 
    })

    nextTick(()=>{
      // 让input自动聚焦
      inputRef.value.focus()
    })
    
  }



  // 点击修改属性的按钮
  const showUpdateDiv = (row:AttrData) => {
    isShowList.value = false

    // attrForm.value = {...row}
    // attrForm.value = _.cloneDeep(row)
    attrForm.value = cloneDeep(row)

    attrForm.value.attrValueList.forEach(item => item.isEdit = false)
  }

  const toEdit  = (row:AttrValueData)=>{
    row.isEdit = true
    nextTick(()=>{
      // 让input自动聚焦
      inputRef.value.focus()
    })
  }


  const toLook = (row:AttrValueData,index:number)=>{
    if(!row.valueName || !row.valueName.trim()){
      ElMessage.error('输入的数据不能是空白')
      attrForm.value.attrValueList.splice(index,1)
      return 
    }
    let isRepeat = attrForm.value.attrValueList.some(item=>{
      if( item !== row){  //some方法返回一个布尔值 判断每一项有无符合条件 符合除了自己的还有数据名相同的数据
        return  item.valueName === row.valueName
      }
    })
     
    if(isRepeat){  // 除了自己属性名还有重复的
      ElMessage.error('输入的数据不能重复')
      // row.valueName = ''
      attrForm.value.attrValueList.splice(index,1)
      return 
    }
    row.isEdit = false  
  }


  const save = async ()=> {
    // 获取请求参数
    let attr = attrForm.value
    //  整理参数
    attr.attrValueList = attr.attrValueList.filter(item=>{
      if(item.valueName !== ''){
        delete item.isEdit
        return true
      }
    })
    if(attr.attrValueList.length === 0){
      return
    }

    try{
      await attrApi.addOrUpdate(attr)
      ElMessage.success('保存平台属性成功')
      isShowList.value = true
      getAttrList()
    }catch(error){
      ElMessage.success('保存平台属性失败')
      isShowList.value = true
    }
  }


  const deleteAttr = async(row:AttrData)=>{
    try {
      await attrApi.delete(row.id as number)
      ElMessage.success('删除平台属性成功')
      getAttrList()
    } catch (error) {
      ElMessage.success('删除平台属性失败')
    }
  }
</script>

<style lang="less" scoped>
</style>
